Shader "Lch/Water"
{
    Properties
    {
        //[MainTexture] _BaseMap("漫射贴图(_BaseMap)", 2D) = "white" {}
        [MainColor] [HDR]_BaseColor("颜色(_BaseColor)", Color) = (1,1,1,1)
        
        [NoScaleOffset]_BumpScale("法线强度（_BumpScale）", Range(0,1)) = 1.0
        _BumpMap("法线(_BumpMap)", 2D) = "bump" {}
        _ReflectBumpPower("反射区域法线",Range(0,1))=0
        _BumpSpeed("水流速度",Vector) = (0.1,0.1,-0.02,-0.164)
        _AlphaCtrl("水透明度控制",Range(0.01,5))=0.01
    
        _Metallic("金属度（Metallic）", Range(0.0, 1.0)) = 0.0
       
       
   
 
        _Smoothness("粗糙度（Smoothness）", Range(0.0, 1.0)) = 0.7
        _FresnelPower("菲涅尔反射控制",Range(1,8)) =  4
        _ReflectDistance("反射距离（_ReflectDistance）", Range(30, 50.0)) = 30.0
        
        //_FresnelStrength("自定义菲涅尔强度（_FresnelStrength）", Range(0.0, 1.0)) = 1
        //_BackLight("背光",Range(0,0.5)) = 0.2

  

        _SpecularMaxLimit("光照最大限制",Range(1.0,50)) = 3.0
    
        

 

        [LCHEnum(LCHblendlModel)] _bendModel("混合模式", Int) = 0
 
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("源混合 SrcBlend", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("目标混合 DstBlend", Float) = 0
 
		[Enum(UnityEngine.Rendering.CullMode)]_Cull("剔除模式", float) = 2

		_OffsetFactor("双材质防穿插,越小越前", Float) = 0
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Transparent"
            "UniversalMaterialType" = "Lit"
            "Queue"="Transparent"
            "DisableBatching"="False"
            "ShaderGraphShader"="true"
            "ShaderGraphTargetId"="UniversalLitSubTarget"
        }
       
        Pass
        {

            Name "Universal Forward"
            Tags
            {
                "LightMode" = "UniversalForward"
            }

       
            ZWrite Off
            Cull[_Cull]
            //Offset -10, 1
            Offset [_OffsetFactor], [_OffsetFactor]
            HLSLPROGRAM
            #define DOUBLE_SIDE
            //#define CUSTOM_GGX
            // GPU Instancing
            //#pragma multi_compile_instancing

            //#pragma shader_feature_local_fragment _ALPHATEST_ON

            //#define CUSTOM_CUBEMAP_BRIGHTNESS
            #define _LIGHT_LAYERS
            #define   _SHADOWS_SOFT
            #define _MAIN_LIGHT_SHADOWS_CASCADE
            //#define    _ADDITIONAL_LIGHTS
        
 
           // #pragma multi_compile   _  LIGHTMAP_ON 

           // #pragma multi_compile SHADOWS_SHADOWMASK

 
           
             

           // #pragma multi_compile _ADDITIONAL_LIGHT_SHADOWS
            //Universal Render Pipeline/Lit, SubShader #0
            //SHADOWS_SHADOWMASK _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHT_SHADOWS _LIGHT_LAYERS _MAIN_LIGHT_SHADOWS_CASCADE _SHADOWS_SOFT
            
 

            //#pragma multi_compile   _ _SSS
            //#pragma multi_compile    ANISOTROPIC_NONE ANISOTROPIC_ON ANISOTROPIC_FLOWMAP


            // #pragma multi_compile    FOG_LINEAR FOG_EXP FOG_EXP2

           #pragma multi_compile   _ FOG_LINEAR    
 
            //_ADDITIONAL_LIGHT_SHADOWS _LIGHT_LAYERS _MAIN_LIGHT_SHADOWS_CASCADE _SHADOWS_SOFT
            #define _NORMALMAP  

            #define MAIN_LIGHT_CALCULATE_SHADOWS
            #ifdef _NORMALMAP
            #define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 

            #endif

            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
          

            #define CUSTOM_VERTEX_PARAM   float4 ScreenPosition : TEXCOORD11;  
            
            #define SCREEN_SPACE_REF

            #define NO_FRESNEL_TERM
            #include "lch_global_buffer.hlsl"
            #include "LchWaterInput.hlsl"
            #include "lch_urp_com.hlsl"
            
            #pragma vertex vert
            #pragma fragment frag
          
            float4 ComputeScreenPos (float4 pos, float projectionSign)
            {
              float4 o = pos * 0.5f;
              o.xy = float2(o.x, o.y * projectionSign) + o.w;
              o.zw = pos.zw;
              return o;
            }

            Varyings vert(Attributes input)
            {
                Varyings output = (Varyings)0;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_TRANSFER_INSTANCE_ID(input, output);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
                FillVaryingsData(input, output);
                output.uv = TRANSFORM_TEX(output.uv, _BumpMap);
               
              
              
                output.ScreenPosition = ComputeScreenPos(output.positionCS );
         

                return output;
            }
           
            half3 CalculateBlinnPhong(Light light, InputData inputData)
            {
                half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
                half3 lightColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
 
                #if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
                    half smoothness = exp2(10 * _SpecularColor.a + 1);
                    lightColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(_SpecularColor.rgb, 1), smoothness);
                #endif

                return lightColor;
            }
           

            float SampleSceneDepth(float2 uv)
            {
                return SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, UnityStereoTransformScreenSpaceTex(uv)).r;
            }
            float getLineNearDepthFromNDC(float2 NDCPosition)
            {
                float _SceneDepth_Out;

                _SceneDepth_Out = Linear01Depth(SampleSceneDepth(NDCPosition.xy), _ZBufferParams);
                float _LinearDepth = _SceneDepth_Out * _ProjectionParams.z;
                return _LinearDepth;
            }
            float getLineNearDepthFromScreenPos(float2 screenPos)
            {
                float _SceneDepth_Out;
                float sceneDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenPos);
                _SceneDepth_Out = Linear01Depth(sceneDepth, _ZBufferParams);
                float _LinearDepth = _SceneDepth_Out * _ProjectionParams.z;
                return _LinearDepth;
            }
            
            half4 frag(Varyings input,bool isFrontFace : SV_IsFrontFace) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                float2 uv = input.uv;
                 //这里的法线是模型的原法线
                half NoV = saturate(dot(input.normalWS.xyz, GetWorldSpaceNormalizeViewDir(input.positionWS)));
                half invNoV = 1.0- NoV;


                float2 screenPos = input.ScreenPosition.xy / input.ScreenPosition.w;
			    float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenPos);
                depth = Linear01Depth(depth, _ZBufferParams);
                float _LinearDepth = depth* _ProjectionParams.z;
 
                // 屏幕位置
                float _LinearDepthSelf = input.ScreenPosition.w ;
   
 
                float _DepthDifference_Out = _LinearDepth - _LinearDepthSelf;
                float _DepthBlendFactor_Out = _DepthDifference_Out * _AlphaCtrl;
                 
 
                float depthDifference =  _DepthBlendFactor_Out  ;
                 
             
               
                LchSurfaceData surfaceData;
                InitializeLchSurfaceData(input.uv, surfaceData,invNoV);

                half3 normalTS = surfaceData.normalTS;
 
                float4 screenColor = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, screenPos+normalTS.xy*0.1 );
 

                #define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR
                InputData inputData;
                InitializeInputData(input,  isFrontFace, normalTS, inputData);
                half3 reflectVector = reflect(-inputData.viewDirectionWS, inputData.normalWS);
               
 
                half fresnelTerm = pow(1.0 - NoV,_FresnelPower);
                surfaceData.metallic = lerp(  surfaceData.metallic,1,fresnelTerm);
                BRDFData brdfData;
                InitializeBRDFData(surfaceData , brdfData);

                
     
                LchAnisoData anisoData;
                InitAnisoData(surfaceData,anisoData,inputData);
                half4 shadowMask = CalculateShadowMask(inputData);
    
                AmbientOcclusionFactor aoFactor;
                aoFactor.directAmbientOcclusion = 1.0;
                aoFactor.indirectAmbientOcclusion = surfaceData.occlusion;
 
                Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
                half3 ambient = inputData.bakedGI.rgb;
 

                
                MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);

                float3 refPosWS = inputData.positionWS + reflectVector *_ReflectDistance;

                SetRefScreenPos(refPosWS);
   
                
                half3 giColor = LchGlobalIllumination(brdfData, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.normalWS, inputData.viewDirectionWS);
    
     
                #ifdef _SSS
                giColor *= surfaceData.sssAmb;
                #endif
                uint meshRenderingLayers = GetMeshRenderingLayer();
                half3 color = giColor; 
      
               
               
 
                if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
                {

                    
                 
       
                    if(surfaceData.backLight>0)
                    {
                        color += LchLightingPhysicallyBasedBackLight(brdfData,anisoData, mainLight.color, mainLight.direction,   mainLight.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS,surfaceData.backLight ) ;  
                    }
                    else
                    {
                        color += LchLightingPhysicallyBased(brdfData,anisoData, mainLight.color, mainLight.direction,   mainLight.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS );  
                    }
                  
                  
                      
                }
 
               #if defined(_ADDITIONAL_LIGHTS)
           
              uint pixelLightCount = GetAdditionalLightsCount();

 
              
                #if USE_CLUSTERED_LIGHTING
                for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
                {
                    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
                    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
                    {
                    
                        color += LchLightingPhysicallyBased(brdfData,anisoData, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS);  
                        
                    }
                    
                }
                #endif
               
                LIGHT_LOOP_BEGIN(pixelLightCount)
                    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
                    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
                    {
                        color += LchLightingPhysicallyBased(brdfData,anisoData, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS);    
                    
                    }
                LIGHT_LOOP_END
                #endif
                #if defined(_ADDITIONAL_LIGHTS_VERTEX)
                lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
                #endif

                color.rgb = min(color.rgb,surfaceData.maxLimit);

                
                color.rgb += surfaceData.emission;

                color.rgb = MixFog(color.rgb, inputData.fogCoord);
                
          
                 
                color.rgb = lerp(screenColor.rgb,color.rgb,surfaceData.alpha *clamp( depthDifference  + fresnelTerm ,0, 1.0));
                return float4(color,1.0);
 
            }
            ENDHLSL
        }

        
        Pass
		{
			
			Name "ShadowCaster"
			Tags { "LightMode"="ShadowCaster" }
			ZWrite On
			ZTest LEqual
			AlphaToMask Off
			ColorMask 0
			HLSLPROGRAM
			#define _NORMAL_DROPOFF_TS 1
			//#pragma multi_compile_instancing
 
		
			#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
            //#pragma multi_compile _ DOTS_INSTANCING_ON

			#pragma vertex vert
			#pragma fragment ShadowPassFragmentFun

			#define SHADERPASS SHADERPASS_SHADOWCASTER

			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl"
            #define CBUFFER_ONLY
            #include "LchWaterInput.hlsl"

			struct VertexInput
			{
				float4 positionOS : POSITION;

                float2 uv                       : TEXCOORD0;
				float3 normalOS : NORMAL;
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct VertexOutput
			{
				  float4 positionCS : SV_POSITION;
                  float2 uv                       : TEXCOORD0;
			 		
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};

 
			float3 _LightDirection;
			float3 _LightPosition;

			VertexOutput VertexFunction( VertexInput v )
			{
				VertexOutput o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );

				float3 positionWS = TransformObjectToWorld( v.positionOS.xyz );
				float3 normalWS = TransformObjectToWorldDir(v.normalOS);
				#if _CASTING_PUNCTUAL_LIGHT_SHADOW
					float3 lightDirectionWS = normalize(_LightPosition - positionWS);
				#else
					float3 lightDirectionWS = _LightDirection;
				#endif

				float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
				#if UNITY_REVERSED_Z
					positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE);
				#else
					positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE);
				#endif
				o.positionCS = positionCS;
                o.uv = v.uv;
				return o;
			}

			 
			VertexOutput vert ( VertexInput v )
			{
				return VertexFunction( v );
			}
 

            half4 ShadowPassFragmentFun(VertexOutput input) : SV_TARGET
            {
                Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff);
                return 0;
            }
			 
			ENDHLSL
		} 

          

        Pass
        {
            Name "Meta"
            Tags{"LightMode" = "Meta"}

            Cull Off

            HLSLPROGRAM
      

            #pragma vertex UniversalVertexMeta
            #pragma fragment UniversalFragmentMetaLitFun

            #pragma shader_feature EDITOR_VISUALIZATION
            //#pragma shader_feature_local_fragment _SPECULAR_SETUP
            //#pragma shader_feature_local_fragment _EMISSION
 
            //#pragma shader_feature_local_fragment _ALPHATEST_ON
 
            #include "LchWaterInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UniversalMetaPass.hlsl"
            half4 UniversalFragmentMetaLitFun(Varyings input) : SV_Target
            {

                LchSurfaceData surfaceData;
                InitializeLchSurfaceData(input.uv, surfaceData,0);
                MetaInput metaInput;
                metaInput.Albedo = surfaceData.albedo.xyz;
                metaInput.Emission = surfaceData.emission;
 
                return UniversalFragmentMeta(input, metaInput);
            }

            ENDHLSL
        }


        Pass
        {
            Name "DepthOnly"
            Tags{"LightMode" = "DepthOnly"}

            ZWrite On
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
   

            #pragma vertex DepthOnlyVertex
            #pragma fragment DepthOnlyFragment

            // -------------------------------------
            // Material Keywords
            //#pragma shader_feature_local_fragment _ALPHATEST_ON
           // #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            //#pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON

            
 
            #include "LchWaterInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
            ENDHLSL
        }

        // This pass is used when drawing to a _CameraNormalsTexture texture
        /*Pass
        {
            Name "DepthNormals"
            Tags{"LightMode" = "DepthNormals"}

            ZWrite On
            Cull[_Cull]

            HLSLPROGRAM
            #pragma exclude_renderers gles gles3 glcore
            #pragma target 4.5

            #pragma vertex DepthNormalsVertex
            #pragma fragment DepthNormalsFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _NORMALMAP
 
            #pragma shader_feature_local_fragment _ALPHATEST_ON
 

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON

 
 
            #include "LchWaterInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"
            ENDHLSL
        }*/
    }
    FallBack "Hidden/Shader Graph/FallbackError"

    CustomEditor "LCHShaderGUIBase" 
}